#ifndef __CoordinationTaskCommunication_h__
#define __CoordinationTaskCommunication_h__

#pragma once


#include "CoordinationTask.h"
#include "CoordinationTaskSync.h"
#include "Communication/Communication.h"


class CoordinationTaskCommunication
	: public CoordinationTask
{
public:
	CoordinationTaskCommunication(const CoordinationSetup* setup, const CoordinationTaskMonitor* taskMonitor);
	~CoordinationTaskCommunication();

	bool LoadFromXML(int roleID, const XmlNodeRef& rootNode);

	virtual const char* GetName() const;
	virtual const char* GetDescription() const;
	virtual ECoordinationState GetActorState(const CoordinationID& coordinationID, const CoordinationActor& actor) const;
	virtual ECoordinationState GetState(const CoordinationID& coordinationID) const;
	virtual bool CanStart(const CoordinationID& coordinationID, const CoordinationActors& assignees) const;
	virtual void Start(const CoordinationID& coordinationID, const CoordinationActors& assignees);
	virtual void Stop(const CoordinationID& coordinationID);
	virtual void Stop(const CoordinationID& coordinationID, const CoordinationActor& actor);
	virtual void Update(float updateTime);
	virtual void Serialize(TSerialize ser);

private:
	typedef struct ActorState
	{
		float timeout;
		CommPlayID playID;
		ECoordinationState state;

		void Serialize(TSerialize ser)
		{
			ser.Value("timeout", timeout);
			if (ser.IsReading())
			{
				playID = CommPlayID();
				state = CoordinationFinished;
			}
/*			else
			{
				ser.Value("playID", playID);
				ser.EnumValue("state", state, CoordinationNotRunning, CoordinationFinished);
			}
*/		}
	};

	typedef std::map<CoordinationActor, ActorState> ActorStates;

	typedef struct RunningCommunication
		: public ICommunicationManager::ICommInstanceListener
	{
		RunningCommunication()
			: state(CoordinationRunning)
			, activeCount(0)
		{
		}

		virtual void OnCommunicationEvent(ICommunicationManager::ECommunicationEvent event, EntityId actorID, 
			const CommPlayID& playID);

		ActorStates actors;
		int activeCount;
		ECoordinationState state;

		void Serialize(TSerialize ser)
		{
			ser.Value("actors", actors);
			ser.Value("activeCount", activeCount);
			ser.EnumValue("state", state, CoordinationNotRunning, CoordinationFinished);
		}
	};

	typedef std::map<CoordinationID, RunningCommunication> RunningCommunications;
	RunningCommunications m_running;

	float m_timeout;

	CommID m_commID;
	CommChannelID m_channelID;
	SCommunicationRequest::EOrdering m_ordering;
	float m_expirity;
	float m_minSilence;

	bool m_ignoreSound;
	bool m_ignoreAnim;

	bool m_isListener;

	CoordinationTaskSync m_sync;

	const CoordinationSetup* m_setup;
	const CoordinationTaskMonitor* m_taskMonitor;
};


#endif //__CoordinationTaskCommunication_h__